from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate,MessagesPlaceholder
from langchain_core.tools import tool
import random
from langchain.agents.format_scratchpad.openai_tools import format_to_openai_tool_messages
from langchain.agents.output_parsers.openai_tools import OpenAIToolsAgentOutputParser
from langchain.agents import AgentExecutor



api_key = "sk-6S0PtpNia71gjcfwSsDPsJ9mGqsVPr2XRQzAx1dHbJS7RW4t"
api_base="https://chatapi.littlewheat.com/v1"

llm = ChatOpenAI(model="gpt-3.5-turbo",api_key=api_key ,base_url=api_base)


prompt = ChatPromptTemplate.from_messages(
    [
        ("system","你是一个非常厉害的AI助手，但不了解实时的一些知识",),
        ("user", "{input}"),
        MessagesPlaceholder(variable_name="agent_scratchpad"),
    ]
)


@tool
def getWeather(loc):
    """
        查询即时天气函数
        :param loc: 必要参数，字符串类型，用于表示查询天气的具体城市名称，\
        注意，中国的城市需要用对应城市的英文名称代替，例如如果需要查询上海市天气，则loc参数需要输入'ShangHai'；
        :return：OpenWeather API查询即时天气的结果，具体URL请求地址为：https://api.openweathermap.org/data/2.5/weather\
        返回结果对象类型为解析之后的JSON格式对象，并用字符串形式进行表示，其中包含了全部重要的天气信息
    """
    temp=random.randint(20,35)
    data = loc+"的当前气温是"+str(temp)
    return data

tools = [getWeather]

llm_with_tools = llm.bind_tools(tools)

agent = (
    {
        "input":lambda x:x["input"],
        "agent_scratchpad":lambda x:format_to_openai_tool_messages(x["intermediate_steps"])
    }
    | prompt | llm_with_tools | OpenAIToolsAgentOutputParser()
)

agentExecutor = AgentExecutor(agent=agent,
                              tools=tools,
                              verbose=True,
                              return_intermediate_steps=True)

#response=agentExecutor.invoke({"input": "查询一下北京今天的天气"})
#response = list(agentExecutor.stream({"input": "查询一下北京今天的天气"}))
response = list(agentExecutor.stream({"input": "对比一下今天北京和大理的温差？"}))
print(response)

[{'actions': [ToolAgentAction(tool='getWeather', tool_input={'loc': 'Beijing'}, log="\nInvoking: `getWeather` with `{'loc': 'Beijing'}`\n\n\n", message_log=[AIMessageChunk(content='', additional_kwargs={'tool_calls': [{'index': 0, 'id': 'call_rdzisWvuDkTObBw5QHR0iSyl', 'function': {'arguments': '{"loc": "Beijing"}', 'name': 'getWeather'}, 'type': 'function'}, {'index': 1, 'id': 'call_xMdgeKs3uZhr499d8cSdoZBS', 'function': {'arguments': '{"loc": "Dali"}', 'name': 'getWeather'}, 'type': 'function'}]}, response_metadata={'finish_reason': 'tool_calls', 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_ded0d14823'}, id='run-4baf8e7a-d881-44f6-bba6-83a60928cb3f', tool_calls=[{'name': 'getWeather', 'args': {'loc': 'Beijing'}, 'id': 'call_rdzisWvuDkTObBw5QHR0iSyl', 'type': 'tool_call'}, {'name': 'getWeather', 'args': {'loc': 'Dali'}, 'id': 'call_xMdgeKs3uZhr499d8cSdoZBS', 'type': 'tool_call'}], tool_call_chunks=[{'name': 'getWeather', 'args': '{"loc": "Beijing"}', 'id': 'call_rdzisWvuDkTObBw5QHR0iSyl', 'index': 0, 'type': 'tool_call_chunk'}, {'name': 'getWeather', 'args': '{"loc": "Dali"}', 'id': 'call_xMdgeKs3uZhr499d8cSdoZBS', 'index': 1, 'type': 'tool_call_chunk'}])], tool_call_id='call_rdzisWvuDkTObBw5QHR0iSyl')], 'messages': [AIMessageChunk(content='', additional_kwargs={'tool_calls': [{'index': 0, 'id': 'call_rdzisWvuDkTObBw5QHR0iSyl', 'function': {'arguments': '{"loc": "Beijing"}', 'name': 'getWeather'}, 'type': 'function'}, {'index': 1, 'id': 'call_xMdgeKs3uZhr499d8cSdoZBS', 'function': {'arguments': '{"loc": "Dali"}', 'name': 'getWeather'}, 'type': 'function'}]}, response_metadata={'finish_reason': 'tool_calls', 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_ded0d14823'}, id='run-4baf8e7a-d881-44f6-bba6-83a60928cb3f', tool_calls=[{'name': 'getWeather', 'args': {'loc': 'Beijing'}, 'id': 'call_rdzisWvuDkTObBw5QHR0iSyl', 'type': 'tool_call'}, {'name': 'getWeather', 'args': {'loc': 'Dali'}, 'id': 'call_xMdgeKs3uZhr499d8cSdoZBS', 'type': 'tool_call'}], tool_call_chunks=[{'name': 'getWeather', 'args': '{"loc": "Beijing"}', 'id': 'call_rdzisWvuDkTObBw5QHR0iSyl', 'index': 0, 'type': 'tool_call_chunk'}, {'name': 'getWeather', 'args': '{"loc": "Dali"}', 'id': 'call_xMdgeKs3uZhr499d8cSdoZBS', 'index': 1, 'type': 'tool_call_chunk'}])]}, {'actions': [ToolAgentAction(tool='getWeather', tool_input={'loc': 'Dali'}, log="\nInvoking: `getWeather` with `{'loc': 'Dali'}`\n\n\n", message_log=[AIMessageChunk(content='', additional_kwargs={'tool_calls': [{'index': 0, 'id': 'call_rdzisWvuDkTObBw5QHR0iSyl', 'function': {'arguments': '{"loc": "Beijing"}', 'name': 'getWeather'}, 'type': 'function'}, {'index': 1, 'id': 'call_xMdgeKs3uZhr499d8cSdoZBS', 'function': {'arguments': '{"loc": "Dali"}', 'name': 'getWeather'}, 'type': 'function'}]}, response_metadata={'finish_reason': 'tool_calls', 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_ded0d14823'}, id='run-4baf8e7a-d881-44f6-bba6-83a60928cb3f', tool_calls=[{'name': 'getWeather', 'args': {'loc': 'Beijing'}, 'id': 'call_rdzisWvuDkTObBw5QHR0iSyl', 'type': 'tool_call'}, {'name': 'getWeather', 'args': {'loc': 'Dali'}, 'id': 'call_xMdgeKs3uZhr499d8cSdoZBS', 'type': 'tool_call'}], tool_call_chunks=[{'name': 'getWeather', 'args': '{"loc": "Beijing"}', 'id': 'call_rdzisWvuDkTObBw5QHR0iSyl', 'index': 0, 'type': 'tool_call_chunk'}, {'name': 'getWeather', 'args': '{"loc": "Dali"}', 'id': 'call_xMdgeKs3uZhr499d8cSdoZBS', 'index': 1, 'type': 'tool_call_chunk'}])], tool_call_id='call_xMdgeKs3uZhr499d8cSdoZBS')], 'messages': [AIMessageChunk(content='', additional_kwargs={'tool_calls': [{'index': 0, 'id': 'call_rdzisWvuDkTObBw5QHR0iSyl', 'function': {'arguments': '{"loc": "Beijing"}', 'name': 'getWeather'}, 'type': 'function'}, {'index': 1, 'id': 'call_xMdgeKs3uZhr499d8cSdoZBS', 'function': {'arguments': '{"loc": "Dali"}', 'name': 'getWeather'}, 'type': 'function'}]}, response_metadata={'finish_reason': 'tool_calls', 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_ded0d14823'}, id='run-4baf8e7a-d881-44f6-bba6-83a60928cb3f', tool_calls=[{'name': 'getWeather', 'args': {'loc': 'Beijing'}, 'id': 'call_rdzisWvuDkTObBw5QHR0iSyl', 'type': 'tool_call'}, {'name': 'getWeather', 'args': {'loc': 'Dali'}, 'id': 'call_xMdgeKs3uZhr499d8cSdoZBS', 'type': 'tool_call'}], tool_call_chunks=[{'name': 'getWeather', 'args': '{"loc": "Beijing"}', 'id': 'call_rdzisWvuDkTObBw5QHR0iSyl', 'index': 0, 'type': 'tool_call_chunk'}, {'name': 'getWeather', 'args': '{"loc": "Dali"}', 'id': 'call_xMdgeKs3uZhr499d8cSdoZBS', 'index': 1, 'type': 'tool_call_chunk'}])]}, {'steps': [AgentStep(action=ToolAgentAction(tool='getWeather', tool_input={'loc': 'Beijing'}, log="\nInvoking: `getWeather` with `{'loc': 'Beijing'}`\n\n\n", message_log=[AIMessageChunk(content='', additional_kwargs={'tool_calls': [{'index': 0, 'id': 'call_rdzisWvuDkTObBw5QHR0iSyl', 'function': {'arguments': '{"loc": "Beijing"}', 'name': 'getWeather'}, 'type': 'function'}, {'index': 1, 'id': 'call_xMdgeKs3uZhr499d8cSdoZBS', 'function': {'arguments': '{"loc": "Dali"}', 'name': 'getWeather'}, 'type': 'function'}]}, response_metadata={'finish_reason': 'tool_calls', 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_ded0d14823'}, id='run-4baf8e7a-d881-44f6-bba6-83a60928cb3f', tool_calls=[{'name': 'getWeather', 'args': {'loc': 'Beijing'}, 'id': 'call_rdzisWvuDkTObBw5QHR0iSyl', 'type': 'tool_call'}, {'name': 'getWeather', 'args': {'loc': 'Dali'}, 'id': 'call_xMdgeKs3uZhr499d8cSdoZBS', 'type': 'tool_call'}], tool_call_chunks=[{'name': 'getWeather', 'args': '{"loc": "Beijing"}', 'id': 'call_rdzisWvuDkTObBw5QHR0iSyl', 'index': 0, 'type': 'tool_call_chunk'}, {'name': 'getWeather', 'args': '{"loc": "Dali"}', 'id': 'call_xMdgeKs3uZhr499d8cSdoZBS', 'index': 1, 'type': 'tool_call_chunk'}])], tool_call_id='call_rdzisWvuDkTObBw5QHR0iSyl'), observation='Beijing的当前气温是33')], 'messages': [FunctionMessage(content='Beijing的当前气温是33', additional_kwargs={}, response_metadata={}, name='getWeather')]}, {'steps': [AgentStep(action=ToolAgentAction(tool='getWeather', tool_input={'loc': 'Dali'}, log="\nInvoking: `getWeather` with `{'loc': 'Dali'}`\n\n\n", message_log=[AIMessageChunk(content='', additional_kwargs={'tool_calls': [{'index': 0, 'id': 'call_rdzisWvuDkTObBw5QHR0iSyl', 'function': {'arguments': '{"loc": "Beijing"}', 'name': 'getWeather'}, 'type': 'function'}, {'index': 1, 'id': 'call_xMdgeKs3uZhr499d8cSdoZBS', 'function': {'arguments': '{"loc": "Dali"}', 'name': 'getWeather'}, 'type': 'function'}]}, response_metadata={'finish_reason': 'tool_calls', 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_ded0d14823'}, id='run-4baf8e7a-d881-44f6-bba6-83a60928cb3f', tool_calls=[{'name': 'getWeather', 'args': {'loc': 'Beijing'}, 'id': 'call_rdzisWvuDkTObBw5QHR0iSyl', 'type': 'tool_call'}, {'name': 'getWeather', 'args': {'loc': 'Dali'}, 'id': 'call_xMdgeKs3uZhr499d8cSdoZBS', 'type': 'tool_call'}], tool_call_chunks=[{'name': 'getWeather', 'args': '{"loc": "Beijing"}', 'id': 'call_rdzisWvuDkTObBw5QHR0iSyl', 'index': 0, 'type': 'tool_call_chunk'}, {'name': 'getWeather', 'args': '{"loc": "Dali"}', 'id': 'call_xMdgeKs3uZhr499d8cSdoZBS', 'index': 1, 'type': 'tool_call_chunk'}])], tool_call_id='call_xMdgeKs3uZhr499d8cSdoZBS'), observation='Dali的当前气温是20')], 'messages': [FunctionMessage(content='Dali的当前气温是20', additional_kwargs={}, response_metadata={}, name='getWeather')]}, {'output': '今天北京的气温是33°C，而大理的气温是20°C。两地的温差是13°C。', 'intermediate_steps': [(ToolAgentAction(tool='getWeather', tool_input={'loc': 'Beijing'}, log="\nInvoking: `getWeather` with `{'loc': 'Beijing'}`\n\n\n", message_log=[AIMessageChunk(content='', additional_kwargs={'tool_calls': [{'index': 0, 'id': 'call_rdzisWvuDkTObBw5QHR0iSyl', 'function': {'arguments': '{"loc": "Beijing"}', 'name': 'getWeather'}, 'type': 'function'}, {'index': 1, 'id': 'call_xMdgeKs3uZhr499d8cSdoZBS', 'function': {'arguments': '{"loc": "Dali"}', 'name': 'getWeather'}, 'type': 'function'}]}, response_metadata={'finish_reason': 'tool_calls', 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_ded0d14823'}, id='run-4baf8e7a-d881-44f6-bba6-83a60928cb3f', tool_calls=[{'name': 'getWeather', 'args': {'loc': 'Beijing'}, 'id': 'call_rdzisWvuDkTObBw5QHR0iSyl', 'type': 'tool_call'}, {'name': 'getWeather', 'args': {'loc': 'Dali'}, 'id': 'call_xMdgeKs3uZhr499d8cSdoZBS', 'type': 'tool_call'}], tool_call_chunks=[{'name': 'getWeather', 'args': '{"loc": "Beijing"}', 'id': 'call_rdzisWvuDkTObBw5QHR0iSyl', 'index': 0, 'type': 'tool_call_chunk'}, {'name': 'getWeather', 'args': '{"loc": "Dali"}', 'id': 'call_xMdgeKs3uZhr499d8cSdoZBS', 'index': 1, 'type': 'tool_call_chunk'}])], tool_call_id='call_rdzisWvuDkTObBw5QHR0iSyl'), 'Beijing的当前气温是33'), (ToolAgentAction(tool='getWeather', tool_input={'loc': 'Dali'}, log="\nInvoking: `getWeather` with `{'loc': 'Dali'}`\n\n\n", message_log=[AIMessageChunk(content='', additional_kwargs={'tool_calls': [{'index': 0, 'id': 'call_rdzisWvuDkTObBw5QHR0iSyl', 'function': {'arguments': '{"loc": "Beijing"}', 'name': 'getWeather'}, 'type': 'function'}, {'index': 1, 'id': 'call_xMdgeKs3uZhr499d8cSdoZBS', 'function': {'arguments': '{"loc": "Dali"}', 'name': 'getWeather'}, 'type': 'function'}]}, response_metadata={'finish_reason': 'tool_calls', 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_ded0d14823'}, id='run-4baf8e7a-d881-44f6-bba6-83a60928cb3f', tool_calls=[{'name': 'getWeather', 'args': {'loc': 'Beijing'}, 'id': 'call_rdzisWvuDkTObBw5QHR0iSyl', 'type': 'tool_call'}, {'name': 'getWeather', 'args': {'loc': 'Dali'}, 'id': 'call_xMdgeKs3uZhr499d8cSdoZBS', 'type': 'tool_call'}], tool_call_chunks=[{'name': 'getWeather', 'args': '{"loc": "Beijing"}', 'id': 'call_rdzisWvuDkTObBw5QHR0iSyl', 'index': 0, 'type': 'tool_call_chunk'}, {'name': 'getWeather', 'args': '{"loc": "Dali"}', 'id': 'call_xMdgeKs3uZhr499d8cSdoZBS', 'index': 1, 'type': 'tool_call_chunk'}])], tool_call_id='call_xMdgeKs3uZhr499d8cSdoZBS'), 'Dali的当前气温是20')], 'messages': [AIMessage(content='今天北京的气温是33°C，而大理的气温是20°C。两地的温差是13°C。', additional_kwargs={}, response_metadata={})]}]